package com.ftrend.printdemo

import android.Manifest
import android.annotation.SuppressLint
import android.app.PendingIntent
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.*
import android.content.pm.PackageManager
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.hardware.usb.UsbManager.ACTION_USB_DEVICE_ATTACHED
import android.hardware.usb.UsbManager.ACTION_USB_DEVICE_DETACHED
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.dantsu.escposprinter.connection.bluetooth.BluetoothConnection
import com.dantsu.escposprinter.connection.bluetooth.BluetoothPrintersConnections
import com.ftrend.printdemo.async.*
import com.ftrend.printdemo.common.*
import com.ftrend.printdemo.common.PrintBarCodeLable
import com.loopstack.gprint.io.EthernetPort
import com.loopstack.gprint.utils.Command
import com.ftrend.printdemo.mhttemplate.PrinterCommon.toPrints
import com.ftrend.printdemo.utlis.BluetoothUtil
import com.loopstack.gprint.io.PrinterDevices
import com.permissionx.guolindev.PermissionX
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.*


class MainActivity : AppCompatActivity(),PrinterManager.CallbackListener {
    companion object{
        const val PERMISSION_BLUETOOTH = 1;
        const val PERMISSION_BLUETOOTH_ADMIN = 2;
        const val PERMISSION_BLUETOOTH_CONNECT = 3;
        const val PERMISSION_BLUETOOTH_SCAN = 4;
        val ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var button:Button =  this.findViewById(R.id.button_bluetooth_browse)
        usbManager = getSystemService(Context.USB_SERVICE) as UsbManager
        printerManager = PrinterManager.getInstance()
        printerManager.setCallbackListener(this)
        button.setOnClickListener(object: View.OnClickListener{
            override fun onClick(p0: View?) {
                val requestList = ArrayList<String>()
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                    requestList.add(Manifest.permission.BLUETOOTH_SCAN)
                    requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE)
                    requestList.add(Manifest.permission.BLUETOOTH_CONNECT)
                }else{
                    requestList.add(Manifest.permission.BLUETOOTH)
                    requestList.add(Manifest.permission.BLUETOOTH_ADMIN)
                    requestList.add(Manifest.permission.BLUETOOTH_CONNECT)
                }
                if (requestList.isNotEmpty()) {
                    PermissionX.init(this@MainActivity)
                        .permissions(requestList)
                        .request { allGranted, grantedList, deniedList ->
                            if (allGranted) {
                                browseBluetoothDevice()
                            } else {
                                Toast.makeText(
                                    this@MainActivity,
                                    "您拒绝了如下权限：$deniedList",
                                    Toast.LENGTH_SHORT
                                ).show()
                            }
                        }
                }
            }
        })
        button =  this.findViewById(R.id.button_bluetooth);
        button.setOnClickListener(object: View.OnClickListener{
            override fun onClick(p0: View?) {
                printBluetooth()
            }
        })
        button =  this.findViewById(R.id.button_usb);
        button.setOnClickListener(object: View.OnClickListener{
            override fun onClick(p0: View?) {
                printUsb()
            }
        })
        button =  this.findViewById(R.id.button_tcp);
        button.setOnClickListener(object: View.OnClickListener{
            override fun onClick(p0: View?) {
                printTcp()
            }
        })
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            when (requestCode) {
                PERMISSION_BLUETOOTH,PERMISSION_BLUETOOTH_ADMIN,PERMISSION_BLUETOOTH_CONNECT,PERMISSION_BLUETOOTH_SCAN->{
                    this.browseBluetoothDevice()
                }
            }
        }
    }


    private lateinit var selectedDevice: BluetoothConnection;

    fun browseBluetoothDevice():Unit {
        val bluetoothDevicesList = BluetoothPrintersConnections().list;
        if (bluetoothDevicesList != null) {

            val items = arrayOfNulls<String>(bluetoothDevicesList.size + 1);
            var i = 0
            items[i] = "Default printer"
            if (ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.BLUETOOTH_CONNECT
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                this.browseBluetoothDevice()
            }
            for (device:BluetoothConnection in bluetoothDevicesList) {
                i++
                items[i] = device.getDevice().getName()
                items[i]?.let {
                    Log.e("browseBluetoothDevice", it)
                }
            }

            val alertDialog =  AlertDialog.Builder(this)
            alertDialog.setTitle("Bluetooth printer selection")

            alertDialog.setItems(items,object : DialogInterface.OnClickListener{
                override fun onClick(p0: DialogInterface?, p1: Int) {
                    selectedDevice = bluetoothDevicesList[p1-1]
                    val  button:Button =this@MainActivity.findViewById(R.id.button_bluetooth_browse);
                    button.setText(items[p1])
                }
            })

            val alert = alertDialog.create();
            alert.setCanceledOnTouchOutside(false);
            alert.show();

        }
    }

    @SuppressLint("SuspiciousIndentation")
    fun printBluetooth():Unit{
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.BLUETOOTH), MainActivity.PERMISSION_BLUETOOTH);
        } else if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,  arrayOf(Manifest.permission.BLUETOOTH_ADMIN), MainActivity.PERMISSION_BLUETOOTH_ADMIN);
        } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S && ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.BLUETOOTH_CONNECT), MainActivity.PERMISSION_BLUETOOTH_CONNECT);
        } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S && ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,  arrayOf(Manifest.permission.BLUETOOTH_SCAN), MainActivity.PERMISSION_BLUETOOTH_SCAN);
        } else {
            closeport(PrintType.BLUE)
            //isConnecting = true;
            printerAddress = selectedDevice.device.address
            printerName = selectedDevice.device.name

                //1、蓝牙设备连接
                //2、发送打印数据
                //3、返回打印状态
            Log.e("123",selectedDevice.device.address)
            val blueTooth =  PrinterDevices.Build()
                .setContext(this)
                .setConnMethod(com.loopstack.gprint.utils.ConnMethod.BLUETOOTH)
                .setMacAddress(selectedDevice.device.address)
                .setCallbackListener(object:
                    com.loopstack.gprint.utils.CallbackListener {
                    override fun onConnecting() {
                        Log.e("PrinterDevices","onConnecting")
                    }

                    override fun onCheckCommand() {
                        Log.e("PrinterDevices","onCheckCommand")
                    }

                    override fun onSuccess(var1: PrinterDevices?) {
//                        Log.e("PrinterDevices","onSuccess")
//                        PrinterBlue.setPrinterCommand(Command.TSC)
//                        PrintBarCodeLable().sendLabel()
                        //Log.e("PrinterDevices",printerName)
                        if (PrinterBlue.getPortManager()!=null&&PrinterBlue.getConnectState()){
                            Log.e("PrinterDevices",printerName)

                            if (printerName.equals("XP-T202UA")||printerName.equals("MHT-L58G")||printerName.equals("Printer_ED3C"))
                            {
                                PrinterBlue.setPrinterCommand(Command.TSC)
                            }else {
                                //PrinterBlue.setPrinterCommand(Command.ESC)
                            }
                            Log.e("PrinterDevices",PrinterBlue.getPrinterCommand().name)
                            when(PrinterBlue.getPrinterCommand()){
                               Command.ESC -> {
                                    PrintOrderUtils.sendReceiptWithResponse()
                                }
                                Command.TSC -> {
                                    PrintBarCodeLable().sendLabel()
                                }
                                else -> {

                                }

                            }
                        }

                    }
                    override fun onReceive(var1: ByteArray?) {
                        Log.e("PrinterDevices","onReceive")
                    }

                    override fun onFailure() {
                        Log.e("PrinterDevices","onFailure")
                    }

                    override fun onDisconnect() {
                        Log.e("PrinterDevices","onDisconnect")
                    }

                }).build()
               PrinterBlue.connect(blueTooth,this)

        }
    }

//    /*==============================================================================================
//    ===========================================USB PART=============================================
//    ==============================================================================================*/

    val usbReceiver: BroadcastReceiver = object:BroadcastReceiver() {
        override fun onReceive(p0: Context?, intent: Intent?) {
            val action = intent!!.getAction()
            when(action){
                ACTION_USB_PERMISSION ->{
                    synchronized(this) {
                        val usbManager = getSystemService(Context.USB_SERVICE) as UsbManager

                        val usbDevice = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)!!

                        if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                            if (usbManager != null && usbDevice != null) {
                                //用户点击授权
                                if (isBar)
                                {
                                    usbConnBar(usbDevice);
                                }else {
                                    usbConn(usbDevice);
                                }
                            }
                        }
                    }
                }
                DeviceConnFactoryManager.ACTION_CONN_STATE->{
                    //Conn
                }
                DeviceConnUsbFactoryManager.ACTION_CONN_STATE->{
                    //ConnUsb
                }
                DeviceConnUsbBarFactoryManager.ACTION_CONN_STATE->{
                    //ConnUsbBar
                }
                BluetoothAdapter.ACTION_STATE_CHANGED->{
                    val blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
                    if (blueState == BluetoothAdapter.STATE_ON) {
                        val isStart = BluetoothUtil.getInstance().startBluetooth(this@MainActivity)
                        if (isStart) {
                            connecting();
                        }
                    }
                }
                BluetoothDevice.ACTION_ACL_DISCONNECTED->{
                    if (DeviceConnFactoryManager.getDeviceConnFactoryManagers()[blue_id] != null) {
                        DeviceConnFactoryManager.getDeviceConnFactoryManagers()[blue_id].setOpenPort(false)
                    }
                }
                ACTION_USB_DEVICE_DETACHED->{

                }
                ACTION_USB_DEVICE_ATTACHED->{
                    //connectUsbPrint(intent)
                }
            }
        }
    }

    private var printerNameUsbBar = ""
    private var printerNameUsb = ""
    private var isBar = false
    private lateinit var usbManager:UsbManager
    private lateinit var mPermissionIntent:PendingIntent
    private lateinit var printerManager:PrinterManager
    private lateinit var printerAddress:String
    private var blue_id = 0
    private var printerName = ""

    @SuppressLint("ServiceCast", "WrongConstant")
    fun printUsb():Unit{
        val  manager = this.getSystemService(Context.USB_SERVICE) as UsbManager
        val devices:HashMap<String, UsbDevice> = manager.deviceList
        val deviceIterator:Iterator<UsbDevice> = devices.values.iterator()
        val count = devices.size
        if (count > 0) {
            while (deviceIterator.hasNext()) {
                val device:UsbDevice = deviceIterator.next()

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && device != null) {
                    val manufacturerName = device.manufacturerName
                    if(manufacturerName!=null){
                        Log.e("manufacturerName",manufacturerName)
                    }
                    var subName = ""
                    try {
                        if(manufacturerName != null && manufacturerName.length>7){
                            subName = manufacturerName.substring(0,7)
                        }
                    }catch (e:Exception){
                        e.printStackTrace()
                    }

                    if (!TextUtils.isEmpty(manufacturerName) && (subName.equals("Printer") || manufacturerName.equals("Printer  ") || manufacturerName.equals("Printer") || manufacturerName.equals("MHT-L58G")|| manufacturerName.equals("Zhuhai Howbest Label Printer Co.,Ltd."))) {
                        //获取USB设备名
                        val deviceName = device.getDeviceName()
                        manufacturerName?.let {
                            printerNameUsbBar = manufacturerName
                        }
                        isBar=true;
                        //通过USB设备名找到USB设备
                        val usbDevices = Utils.getUsbDeviceFromName(this, deviceName);
                        //判断USB设备是否有权限

                        if (usbManager.hasPermission(usbDevices)) {
//                            if (manufacturerName.equals("Printer  ")||manufacturerName.equals("MHT-L58G")||manufacturerName.equals("Printer")) {
//                                SharedPreferencesUtil.putBoolean(mContext, BaseConst.SHP_KEY_IS_GP_PRINT, false);
//                            } else {
//                                SharedPreferencesUtil.putBoolean(mContext, BaseConst.SHP_KEY_IS_GP_PRINT, true);
//                            }
                            usbConnBar(usbDevices);
                            toPrints(manufacturerName,this)
                            //PrintBarCodeLable().sendLabel()
                        } else {//请求权限
                            mPermissionIntent = PendingIntent.getBroadcast(this, 0, Intent(ACTION_USB_PERMISSION), 0);
                            usbManager.requestPermission(usbDevices, mPermissionIntent);
                        }
                    } else if (!TextUtils.isEmpty(manufacturerName) && (manufacturerName.equals("Xprinter") || manufacturerName.equals("Xprinter ") || manufacturerName.equals("mht") ||manufacturerName.equals("Gprinter") || manufacturerName.equals("GPrinter") || manufacturerName.equals("ZHU HAI SUNCSW Receipt PrinterBlue Co.,Ltd") || manufacturerName.equals("ZHU HAI SUNCSW Receipt Printer Co.,Ltd"))) {
                        //获取USB设备名
                        val deviceName = device.getDeviceName()
                        manufacturerName?.let {
                            printerNameUsb = manufacturerName
                        }
                        isBar=false
                        //  Utils.toast(getActivity(), "打印机连接--" + usbName);
                        //通过USB设备名找到USB设备
                        val usbDevices = Utils.getUsbDeviceFromName(this, deviceName)
                        //判断USB设备是否有权限
                        if (usbManager.hasPermission(usbDevices)) {
                            usbConn(usbDevices)
                            PrintOrderUtils.sendReceiptWithResponse()
                        } else {//请求权限
                            mPermissionIntent = PendingIntent.getBroadcast(this, 0,  Intent(ACTION_USB_PERMISSION), 0);
                            usbManager.requestPermission(usbDevices, mPermissionIntent)
                        }
                    }
                }
            }
        }
    }

    fun connecting():Unit{
        closeport(PrintType.BLUE)
        printerManager?.let {
            printerManager.connectBlueTooth(this, printerAddress)
        }
    }

    /**
     * usb连接
     *
     * @param usbDevice
     */
    fun usbConn(usbDevice:UsbDevice):Unit {
        closeport(PrintType.TICKET_USB)
        printerManager?.let{
            printerManager.connectUsb(this, PrintType.TICKET_USB, usbDevice)
        }
    }

    /**
     * usb连接
     *
     * @param usbDevice
     */
    fun usbConnBar( usbDevice:UsbDevice):Unit{
        closeport(PrintType.BAR_USB)
        printerManager?.let{
            printerManager.connectUsb(this, PrintType.BAR_USB, usbDevice)
        }
    }

    fun closeport(ticketUsb: PrintType):Unit {
        printerManager?.let{
            printerManager.disConnect(ticketUsb);
        }
    }
    /*==============================================================================================
    =========================================TCP PART===============================================
    ==============================================================================================*/
    private lateinit var ethernetPort: EthernetPort

    fun printTcp():Unit{
        val ipAddress: EditText = this.findViewById(R.id.edittext_tcp_ip)
        val portAddress:EditText = this.findViewById(R.id.edittext_tcp_port)
        val ethernetPrinter =  PrinterDevices.Build()
            .setConnMethod(com.loopstack.gprint.utils.ConnMethod.WIFI)
            .setContext(this)
            .setIp(ipAddress.text.toString())
            .setPort(portAddress.text.toString().toInt())
            .setCallbackListener(object:
                com.loopstack.gprint.utils.CallbackListener {
                override fun onConnecting() {
                    Log.e("ethernet","onConnecting")
                }

                override fun onCheckCommand() {
                    Log.e("ethernet","onCheckCommand")
                }

                override fun onSuccess(var1: PrinterDevices?) {
                    Log.e("ethernet","onSuccess")
                    //ethernetPort.writeDataImmediately("".encodeToByteArray())
                    MainScope().launch {
                        withContext(Dispatchers.IO){
                            PrintOrderUtils.sendReceiptWithResponse()
                        }
                    }
                }

                override fun onReceive(var1: ByteArray?) {

                }

                override fun onFailure() {

                }

                override fun onDisconnect() {

                }

            })
            .build()
        PrinterEthernet.connect(ethernetPrinter, this);

    }
    override fun onConnecting(printType: PrintType?) {

    }

    override fun onSuccess(printType: PrintType?) {

    }

    override fun onFailure(printType: PrintType?) {

    }

    override fun onDisconnect(printType: PrintType?) {

    }

}

